package com.UdpRecieve.Netty.server.handler;


import com.UdpRecieve.Netty.codec.Codec;
import com.UdpRecieve.Netty.protocol.FilePacket;
import com.UdpRecieve.Netty.protocol.Packet;
import com.UdpRecieve.Netty.protocol.serilizer.Serilizer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.DefaultFileRegion;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class FileSendServerHandler extends ChannelInboundHandlerAdapter {

    @Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		ByteBuf byteBuf = (ByteBuf) msg;
		int type = byteBuf.getInt(0);
		if (type == Codec.TYPE) {
			System.out.println("channelId:"+ctx.channel().remoteAddress());

			Packet packet = Codec.INSTANCE.decode(byteBuf);//new Codec();
			ctx.pipeline().remove("length");//audit by cq
			if (packet instanceof FilePacket) {
				FilePacket filePacket = (FilePacket) packet;
				if (filePacket.getACK() != 0) {
					writeAndFlushFileRegion(ctx, filePacket);
				} else {
					super.channelRead(ctx, packet);
				}
			} else {
				super.channelRead(ctx, packet);
			}
		}
	}

   /* public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		ByteBuf byteBuf = (ByteBuf) msg;
		int i = byteBuf.readInt();//type
		Byte command = byteBuf.readByte();//内容(1\2\3)
		int len = byteBuf.readInt();
		ctx.pipeline().a
		if (byteBuf.getInt(0) == Codec.TYPE) {
			ctx.channel().attr(AttributeKey.valueOf("length")).set(byteBuf.getInt(5) + 9 + "");
			ctx.channel().attr(AttributeKey.valueOf("hasRead")).set(byteBuf.readableBytes()+"");
//			int i = byteBuf.readInt();//type
//			Byte command = byteBuf.readByte();//内容(1\2\3)
			int len = byteBuf.readableBytes();
			byte[] bytes = new byte[byteBuf.readableBytes()];
			byteBuf.readBytes(bytes);
			ctx.channel().attr(AttributeKey.valueOf("hasByte")).set(bytes);
			if(len < byteBuf.getInt(5) + 9){
				return;
			}
		} else {
			long hasRead1 = Long.parseLong(ctx.channel().attr(AttributeKey.valueOf("hasRead")).get().toString());
			ctx.channel().attr(AttributeKey.valueOf("hasRead")).set(byteBuf.readableBytes()+hasRead1+"");
			byte[] bytes2 = new byte[(int)(byteBuf.readableBytes()+hasRead1)];
			byte[] old  = (byte[])ctx.channel().attr(AttributeKey.valueOf("hasByte")).get();
			byte[] newBytes = new byte[byteBuf.readableBytes()];
			System.arraycopy(old, 0, bytes2, 0, old.length);
			System.arraycopy(newBytes, 0, bytes2, old.length, newBytes.length);
			ctx.channel().attr(AttributeKey.valueOf("hasByte")).set(bytes2);
		}

		long hasRead = Long.parseLong(ctx.channel().attr(AttributeKey.valueOf("hasRead")).get().toString()) ;
		if(hasRead >= Long.parseLong(ctx.channel().attr(AttributeKey.valueOf("length")).get().toString())){
			byte[] old  = (byte[])ctx.channel().attr(AttributeKey.valueOf("hasByte")).get();
			byte[] b1 = new byte[(int)(hasRead-9)];
			System.arraycopy(old, 9, b1, 0, (int)(hasRead-9));
//			System.out.println(JSONArray.parseObject(b1,FilePacket.class));
			FilePacket packet = JSONArray.parseObject(b1,FilePacket.class);;
			ctx.channel().attr(AttributeKey.valueOf("hasHead")).set(1 + "");
            if (packet instanceof FilePacket) {
                FilePacket filePacket = (FilePacket) packet;
                if (filePacket.getACK() != 0) {
                    writeAndFlushFileRegion(ctx, filePacket);
                } else {
                    super.channelRead(ctx, packet);
                }
            } else {
                super.channelRead(ctx, packet);
            }
			ctx.channel().attr(AttributeKey.valueOf("hasHead")).set(1+"");
		}


    }*/


    private void writeAndFlushFileRegion(ChannelHandlerContext ctx, FilePacket packet) {
        File file = packet.getFile();
        DefaultFileRegion fileRegion = new DefaultFileRegion(file, 0, file.length());
        ctx.writeAndFlush(fileRegion).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println("发送完成...");
                ctx.close();
				/*ctx.pipeline().remove(this);
				ctx.deregister();*/
            }
        });
    }

}
